//和信号相关的函数
#include <string.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <errno.h>
#include <sys/wait.h>

#include "global.h"
#include "macro.h"
#include "function.h"

//与信号相关的结构
typedef struct {
	int   sig_number;    //信号对应的编号
	const char *sig_name;//信号对应的名称
	void (*handler)(int sig_number, siginfo_t *sig_info, void *context);
}signal_t;

static void SignalHandler(int sig_number, siginfo_t *sig_info, void *context);
static void ProcessGetStatus(void); //获取子进程的结束状态

//定义需要处理的各种信号
signal_t signals[] = {
	{SIGHUP,  "SIGHUP",          SignalHandler},
	{SIGINT,  "SIGINT",          SignalHandler},
	{SIGTERM, "SIGTERM",         SignalHandler},
	{SIGCHLD, "SIGCHLD",         SignalHandler},
	{SIGQUIT, "SIGQUIT",         SignalHandler},
	{SIGIO,   "SIGIO",           SignalHandler},
	{SIGSYS,  "SIGSYS, SIG_IGN", NULL},
	{0,       NULL,              NULL}
};

//初始化信号函数
//返回值：0成功，-1失败
int InitSignals() {
	signal_t         *sig;
	struct sigaction sa;

	for(sig = signals; sig->sig_number; sig++) {
		memset(&sa, 0, sizeof(struct sigaction));

		if(sig->handler) {
			sa.sa_sigaction = sig->handler;
			sa.sa_flags     = SA_SIGINFO;  //设置为SA_SIGINFO，表明信号附带的参数可以被传递到信号处理函数中
		}
		else {
			sa.sa_handler  = SIG_IGN;//表示忽略该信号的处理程序
		}

		sigemptyset(&sa.sa_mask);
		//设置信号处理动作
		if(sigaction(sig->sig_number, &sa, NULL) == -1) {
			LogErrorCore(LOG_EMERG, errno, "sigaction(%s) failed", sig->sig_name);
			return -1;
		}
		else {
		
		}
	}
	return 0;
}


//信号处理函数
static void SignalHandler(int sig_number, siginfo_t *sig_info, void *context) {
	signal_t *sig;
	char     *action;

	for(sig = signals; sig->sig_number; sig++) {
		if(sig->sig_number == sig_number) {
			break;
		}
	}

	action = (char *)"";

	if(process == PROCESS_MASTER) {
		switch(sig_number) {
		case SIGCHLD://子进程退出发出的信号
			reap = 1;
			break;
		}
	}
	else if(process == PROCESS_WORKER) {
	
	}
	else {
	
	}

	if(sig_info && sig_info->si_pid) {
		LogErrorCore(LOG_NOTICE, 0, "signal %d (%s) recevied from %P%s", sig_number, sig->sig_name, sig_info->si_pid, action);
	}
	else {
		LogErrorCore(LOG_NOTICE, 0, "signal %d (%s) recevied %s", sig_number, sig->sig_name, action);
	}

	if(sig_number == SIGCHLD) {
		ProcessGetStatus();
	}
	return;
}

//获取子进程的结束状态，防止kill子进程时变成僵尸进程
static void ProcessGetStatus(void) {
	pid_t pid;
	int status;
	int err;
	int one = 0;

	for(;;) {
		//获取子进程的状态信息
		pid = waitpid(-1, &status, WNOHANG);

		if(pid == 0) {//子进程没有结束
			return;
		}
		if(pid == -1) {
			err = errno;
			if(err == EINTR) {//调用被某个信号中断
				continue;
			}
			if(err == ECHILD && one) {//没有子进程
				break;
			}
			if(err == ECHILD) {
				LogErrorCore(LOG_INFO, err, "waitpid() failed!");
				return;
			}
			LogErrorCore(LOG_ALERT, err, "waitpid() failed!");
			return;
		}

		one = 1;
		if(WTERMSIG(status)) {
			//获取使子进程终止的信号编号
			LogErrorCore(LOG_ALERT, 0, "pid = %P exited on signal %d!", pid, WTERMSIG(status));
		}
		else {
			LogErrorCore(LOG_NOTICE, 0, "pid = %P exited with code %d!", pid, WEXITSTATUS(status));
		}
	}
	return;
}






